package api

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"github.com/jiedan/student-web/server/model"
	"gorm.io/gorm"
)

// CourseHandler 课程处理器
type CourseHandler struct {
	DB *gorm.DB
}

// NewCourseHandler 创建课程处理器
func NewCourseHandler(db *gorm.DB) *CourseHandler {
	return &CourseHandler{DB: db}
}

// GetCourses 获取所有课程
func (h *CourseHandler) GetCourses(c *gin.Context) {
	var courses []model.Course
	result := h.DB.Preload("Teacher.User").Find(&courses)
	if result.Error != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get courses"})
		return
	}

	c.JSON(http.StatusOK, courses)
}

// GetCourse 获取单个课程
func (h *CourseHandler) GetCourse(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid course ID"})
		return
	}

	var course model.Course
	result := h.DB.Preload("Teacher.User").First(&course, id)
	if result.Error != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Course not found"})
		return
	}

	c.JSON(http.StatusOK, course)
}

// CreateCourseRequest 创建课程请求
type CreateCourseRequest struct {
	CourseID    string  `json:"course_id" binding:"required"`
	Name        string  `json:"name" binding:"required"`
	Description string  `json:"description"`
	Credits     float64 `json:"credits" binding:"required"`
	Capacity    int     `json:"capacity" binding:"required"`
	TeacherID   uint    `json:"teacher_id" binding:"required"`
	Semester    string  `json:"semester" binding:"required"`
}

// CreateCourse 创建课程
func (h *CourseHandler) CreateCourse(c *gin.Context) {
	var req CreateCourseRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"})
		return
	}

	// 检查课程ID是否已存在
	var existingCourse model.Course
	result := h.DB.Where("course_id = ?", req.CourseID).First(&existingCourse)
	if result.Error == nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Course ID already exists"})
		return
	}

	// 检查教师是否存在
	var teacher model.Teacher
	result = h.DB.First(&teacher, req.TeacherID)
	if result.Error != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Teacher not found"})
		return
	}

	// 创建课程
	course := model.Course{
		CourseID:    req.CourseID,
		Name:        req.Name,
		Description: req.Description,
		Credits:     req.Credits,
		Capacity:    req.Capacity,
		TeacherID:   req.TeacherID,
		Semester:    req.Semester,
	}

	result = h.DB.Create(&course)
	if result.Error != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create course"})
		return
	}

	c.JSON(http.StatusCreated, gin.H{"message": "Course created successfully", "course": course})
}

// UpdateCourseRequest 更新课程请求
type UpdateCourseRequest struct {
	Name        string  `json:"name"`
	Description string  `json:"description"`
	Credits     float64 `json:"credits"`
	Capacity    int     `json:"capacity"`
	TeacherID   uint    `json:"teacher_id"`
	Semester    string  `json:"semester"`
}

// UpdateCourse 更新课程
func (h *CourseHandler) UpdateCourse(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid course ID"})
		return
	}

	var req UpdateCourseRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"})
		return
	}

	// 查找课程
	var course model.Course
	result := h.DB.First(&course, id)
	if result.Error != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Course not found"})
		return
	}

	// 如果更新教师ID，检查教师是否存在
	if req.TeacherID != 0 {
		var teacher model.Teacher
		result = h.DB.First(&teacher, req.TeacherID)
		if result.Error != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "Teacher not found"})
			return
		}
		course.TeacherID = req.TeacherID
	}

	// 更新课程信息
	if req.Name != "" {
		course.Name = req.Name
	}
	if req.Description != "" {
		course.Description = req.Description
	}
	if req.Credits != 0 {
		course.Credits = req.Credits
	}
	if req.Capacity != 0 {
		course.Capacity = req.Capacity
	}
	if req.Semester != "" {
		course.Semester = req.Semester
	}

	// 保存更新
	result = h.DB.Save(&course)
	if result.Error != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update course"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Course updated successfully"})
}

// DeleteCourse 删除课程
func (h *CourseHandler) DeleteCourse(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid course ID"})
		return
	}

	// 查找课程
	var course model.Course
	result := h.DB.First(&course, id)
	if result.Error != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Course not found"})
		return
	}

	// 开始事务
	tx := h.DB.Begin()

	// 删除课程的选课记录
	if err := tx.Where("course_id = ?", id).Delete(&model.CourseSelection{}).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete course selections"})
		return
	}

	// 删除课程的成绩记录
	if err := tx.Where("course_id = ?", id).Delete(&model.Grade{}).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete grades"})
		return
	}

	// 删除课程记录
	if err := tx.Delete(&course).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete course"})
		return
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to commit transaction"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Course deleted successfully"})
}